use std::any::Any;

use crate::id::IdPath;

pub struct Message {
    pub id_path: IdPath,
    pub body: Box<dyn Any>,
}

pub enum EventResult<A> {
    /// event handler returned an action
    Action(A),
    /// event handler request view rebuild
    RequestRebuild,
    /// event was rejected
    Nop,
    /// widget was not found.
    ///
    /// This is a normal outcome for async operation when the tree is changing
    /// dynamically, but otherwise indicates a logic error.
    Stale(Box<dyn Any>),
}

impl<A> EventResult<A> {
    pub fn or(self, f: impl FnOnce(Box<dyn Any>) -> Self) -> Self {
        match self {
            EventResult::Stale(body) => f(body),
            _ => self,
        }
    }
}

impl Message {
    pub fn new(id_path: IdPath, event: impl Any) -> Message {
        Message {
            id_path,
            body: Box::new(event),
        }
    }
}
